package cn.bonoon.kernel.web.controllers;

import javax.servlet.ServletContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.ui.Model;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.servlet.ModelAndView;

import cn.bonoon.kernel.security.AuthenticatedUserDetails;
import cn.bonoon.kernel.util.StringHelper;
import cn.bonoon.kernel.web.models.JsonResult;

/**
 * <pre>
 * 公共的控制器父类的内容：
 * <hr/>
 * 1.
 * 2.
 * </pre>
 * 
 * @author jackson
 * 
 */
public abstract class AbstractController extends AuthenticatedUserDetails implements ApplicationContextAware, ServletContextAware, InitializingBean {
	protected final Logger log = LoggerFactory.getLogger(this.getClass());

	private final static String DEFAULT_ERROR = "error";
	private final static String DEFAULT_ERROR_DIALOG_VM = "dialog-error";
	private final static String DEFAULT_ERROR_PANEL_VM = "panel-error";
	private final static String DEFAULT_ERROR_MARK = "error";

	private String error = DEFAULT_ERROR;
	
	/** 在模板里的标示符 */
	private String errorMark = DEFAULT_ERROR_MARK;
	private String errorDialog = DEFAULT_ERROR_DIALOG_VM;
	private String errorPanel = DEFAULT_ERROR_PANEL_VM;

	protected ServletContext servletContext;
	protected ApplicationContext applicationContext;

	/**  写异常的日志文件，该方法是写到log日志里，不会被写到数据库日志里。 */
	protected void log(Throwable t) {
		t.printStackTrace();
		log.error("操作异常", t);
	}

	protected JsonResult returnError(Throwable t) {
		log(t);
		return JsonResult.error(t);
	}
	
	@Override
	public void setServletContext(ServletContext sc) {
		this.servletContext = sc;
	}
	
	@Override
	public void afterPropertiesSet() throws Exception { }

	public ServletContext getServletContext() {
		return servletContext;
	}

	protected String getContextPath() {
		return servletContext.getContextPath();
	}
	
	protected String toUrl(String url) {
		return StringHelper.path(servletContext.getContextPath(), url);
	}

	protected final String redirect(String url) {
		return "redirect:" + url;
	}

	protected final String forward(String url) {
		return "forward:" + url;
	}

	public final void setApplicationContext(ApplicationContext context) throws BeansException {
		applicationContext = context;
	}

	protected final ApplicationContext getApplicationContext() {
		return applicationContext;
	}

	/** 以对话框的形式弹出错误的提示 */
	protected ModelAndView errorDialog(String error) {
		ModelAndView model = new ModelAndView(errorDialog);
		model.addObject(errorMark, error);
		model.addObject("layout", "layout-empty.vm");
		model.addObject("iconCls", "icon-error");
		model.addObject("title", "异常提示");
		return model;
	}

	protected ModelAndView errorDialog(Throwable t) {
		log(t);
		return errorDialog(t.getMessage());
	}

	protected String errorPanel(Model model, String error) {
		model.addAttribute(errorMark, error);
		return errorPanel;
	}

	protected ModelAndView errorPanel(Throwable t) {
		log(t);
		return new ModelAndView(errorPanel, errorMark, t.getMessage());
	}

	protected String getError() {
		return error;
	}

	protected void setError(String error) {
		this.error = error;
	}

	protected String getError(Throwable t) {
		t.printStackTrace();
		return error;
	}
}
